package com.allwees.bs.c.module.order.context.compute.strategy.coupon;

import com.allwees.bs.c.module.order.context.bo.CouponComputeBo;
import com.allwees.bs.c.module.order.context.bo.UserCouponBo;
import com.allwees.core.common.util.MoneyUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public abstract class CouponStrategy {

    private static List<CouponStrategy> STRATEGY_CACHE = new ArrayList<>(2);

    public abstract CouponComputeBo use(UserCouponBo coupon, CouponComputeBo bo);

    public abstract boolean isSupport(UserCouponBo coupon);

    public static CouponComputeBo strategy(UserCouponBo coupon, CouponComputeBo bo) {
        if (coupon == null || bo == null) {
            return bo;
        }

        if (coupon.getOverdueTime() != null && coupon.getOverdueTime().getTime() < new Date().getTime()) {
            return bo;
        }

        for (CouponStrategy strategy : STRATEGY_CACHE) {
            if (strategy.isSupport(coupon)) {
                return strategy.use(coupon, bo);
            }
        }
        return bo;
    }

    static {
        STRATEGY_CACHE.add(new CouponDiscountStrategy());
        STRATEGY_CACHE.add(new CouponDeductStrategy());
    }

    protected static BigDecimal sub(BigDecimal allAmtProduct, BigDecimal hisAmtProduct) {
        return MoneyUtil.sub(allAmtProduct, hisAmtProduct);
    }

    protected static BigDecimal mul(BigDecimal amtProduct, BigDecimal ratio) {
        return MoneyUtil.mul(amtProduct, ratio);
    }

    protected static BigDecimal div(BigDecimal maxDeductAmt, BigDecimal amtProduct) {
        return MoneyUtil.div(maxDeductAmt, amtProduct, 10);
    }

    protected static BigDecimal realAmtProduct(BigDecimal amtProduct, BigDecimal ratio) {
        return MoneyUtil.sub(amtProduct, mul(amtProduct, ratio));
    }

    protected static boolean last(int length, int i) {
        return length - i == 1;
    }
}
